
#include "config/IncludeParts.h"

#if USE_XML

#include "XmlTab.h"
#include "tools/StringManager.h"
#include <assert.h>

using namespace unixml;

XmlTab::XmlTab(uint16* code, int32 start):
m_code(code),
m_name(0),
m_start(start),
m_end(-1)
{
    init();
}

XmlTab::~XmlTab()
{
    uni_delete(m_name);
    for(int32 i = 0, size = m_attributeNames.size(); i < size; ++i)
    {
        delete[] m_attributeNames[i];
        delete[] m_attributeValues[i];
    }
}

void XmlTab::init()
{
    m_end = unigame::StringManager::uniFindChar('>', m_code, m_start + 1) + 1;
    assert(m_end != 0 && "xml tab not close");
	int32 start = unigame::StringManager::uniFindNextNotBlank(m_code, m_start + 1, m_end - 1);
	int32 end = start;
	if(start != -1)
	{
		end = unigame::StringManager::uniFindChar(' ', m_code, start, m_end - 1);
		if(end == -1)
		{
			end = m_end - 1;
		}
	}
    else
    {
        assert(false && "xml node has no name");
    }
	int32 len = end - start;
	m_name = uni_new uint16[len + 1];
	memcpy(m_name, m_code + start, len * sizeof(uint16));
	m_name[len] = 0;
    makeAttribute(end + 1);
}
        
void XmlTab::makeAttribute(int32 start)
{
    if(start >= m_end - 1)
    {
        return;
    }
    start = unigame::StringManager::uniFindNextNotBlank(m_code, start, m_end - 1);
    if(start == -1)
    {
        return;
    }
    int32 pointer = unigame::StringManager::uniFindChar('=', m_code, start, m_end);
    while(pointer != -1)
    {
        int32 end = pointer;
        unigame::StringManager::uniTrimStr(m_code, &start, &end);
        int32 len = end - start;
        uint16* key = uni_new uint16[len + 1];
        memcpy(key, m_code + start, len * sizeof(uint16));
        key[len] = 0;
        start = unigame::StringManager::uniFindChar('"', m_code, pointer + 1, m_end);
        assert(start != -1 && "attribute wrong");
        ++start;
        end = unigame::StringManager::uniFindChar('"', m_code, start + 1, m_end);
        assert(end != -1 && "attribute wrong");
        len = end - start;
        uint16* value = uni_new uint16[len + 1];
        memcpy(value, m_code + start, len * sizeof(uint16));
        value[len] = 0;
        m_attributeNames.push_back(key);
        m_attributeValues.push_back(value);
        start = end + 1;
        pointer = unigame::StringManager::uniFindChar('=', m_code, start, m_end);
    }
}

uint16* XmlTab::getAttribute(const uint16 *name)
{
    for(int32 i = 0, size = m_attributeNames.size(); i < size; ++i)
    {
        if(unigame::StringManager::uniCompare(name, m_attributeNames[i]) == 0)
        {
            return m_attributeValues[i];
        }
    }
    return 0;
}

#endif